defmodule Stripe.ConverterTest do
  use ExUnit.Case

  alias Stripe.Converter

  test "converts a 'customer.updated' event response properly" do
    expected_result = %Stripe.Event{
      account: "acct_0000000000000000",
      api_version: "2016-07-06",
      created: 1_483_537_031,
      data: %{
        object: %Stripe.Customer{
          id: "cus_9ryX7lUQ4Dcpf7",
          object: "customer",
          created: 1_483_535_628,
          currency: nil,
          default_source: nil,
          delinquent: false,
          description: nil,
          email: "test2@mail.com",
          livemode: false,
          metadata: %{},
          sources: %Stripe.List{
            object: "list",
            data: [],
            has_more: false,
            total_count: 0,
            url: "/v1/customers/cus_9ryX7lUQ4Dcpf7/sources"
          },
          subscriptions: %Stripe.List{
            object: "list",
            data: [],
            has_more: false,
            total_count: 0,
            url: "/v1/customers/cus_9ryX7lUQ4Dcpf7/subscriptions"
          }
        },
        previous_attributes: %{
          description: "testcustomer",
          email: "test@mail.com",
          metadata: %{test: "key"}
        }
      },
      id: "evt_19YEx1BKl1F6IRFfb1cFLHzZ",
      livemode: false,
      object: "event",
      pending_webhooks: 0,
      request: "req_9ryusbEBenV0BX",
      type: "customer.updated"
    }

    fixture = Helper.load_fixture("event_with_customer.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts review.opened event properly" do
    expected_result = %Stripe.Event{
      account: "acct_445dwy73iNyGMfgu",
      api_version: "2019-02-19",
      created: 1_551_702_604,
      data: %{
        object: %Stripe.Review{
          billing_zip: nil,
          charge: "ch_1EAFvj73iNyGMfgutk44a8nD",
          closed_reason: nil,
          created: 1_551_702_603,
          id: "prv_1EAFvj73iNyGMfgu81yzEb0D",
          ip_address: "172.16.1.4",
          ip_address_location: %{
            city: "Samara",
            country: "RU",
            latitude: 34,
            longitude: 33,
            region: "65"
          },
          livemode: false,
          object: "review",
          open: true,
          opened_reason: "rule",
          payment_intent: nil,
          reason: "rule",
          session: %{
            browser: "Firefox",
            device: "Other",
            platform: "Mac OS X 10.14",
            version: "65.0"
          }
        }
      },
      id: "evt_1EAFvk73iNyGMfguDACcQT5X",
      livemode: false,
      object: "event",
      pending_webhooks: 4,
      request: %{
        id: "req_3zmMCPEWZ2R24x",
        idempotency_key: "1551702602859892291_xgpCTQ"
      },
      type: "review.opened"
    }

    fixture = Helper.load_fixture("review_opened.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts a list response properly" do
    expected_result = %Stripe.List{
      object: "list",
      data: [
        %Stripe.Card{
          id: "card_19YDiuBKl1F6IRFflldIp6Dc",
          object: "card",
          address_city: nil,
          address_country: nil,
          address_line1: nil,
          address_line1_check: nil,
          address_line2: nil,
          address_state: nil,
          address_zip: nil,
          address_zip_check: nil,
          brand: "Visa",
          country: "US",
          customer: "cus_9ryX7lUQ4Dcpf7",
          cvc_check: nil,
          dynamic_last4: nil,
          exp_month: 8,
          exp_year: 2018,
          funding: "credit",
          last4: "4242",
          metadata: %{},
          name: nil,
          tokenization_method: nil
        },
        %Stripe.Card{
          id: "card_abcdiuBKl1F6IRFflldIp6Dc",
          object: "card",
          address_city: nil,
          address_country: nil,
          address_line1: nil,
          address_line1_check: nil,
          address_line2: nil,
          address_state: nil,
          address_zip: nil,
          address_zip_check: nil,
          brand: "Visa",
          country: "US",
          customer: "cus_9ryX7lUQ4Dcpf7",
          cvc_check: nil,
          dynamic_last4: nil,
          exp_month: 12,
          exp_year: 2020,
          funding: "credit",
          last4: "4242",
          metadata: %{},
          name: nil,
          tokenization_method: nil
        }
      ],
      has_more: false,
      total_count: 2,
      url: "/v1/customers/cus_9ryX7lUQ4Dcpf7/sources"
    }

    fixture = Helper.load_fixture("card_list.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts a search result response properly" do
    expected_result = %Stripe.SearchResult{
      data: [
        %Stripe.Customer{
          address: nil,
          balance: 0,
          created: 1_656_364_912,
          currency: "usd",
          default_source: nil,
          delinquent: false,
          description: nil,
          discount: nil,
          email: nil,
          id: "cus_LxK1UWzf44dEKX",
          invoice_prefix: "2B6E364",
          invoice_settings: %{
            custom_fields: nil,
            default_payment_method: nil,
            footer: nil,
            rendering_options: nil
          },
          livemode: false,
          metadata: %{"foo" => "bar"},
          name: "fakename",
          next_invoice_sequence: 1,
          object: "customer",
          phone: nil,
          preferred_locales: [],
          shipping: nil,
          sources: nil,
          subscriptions: nil,
          tax_exempt: "none",
          tax_ids: nil
        }
      ],
      has_more: false,
      next_page: nil,
      object: "search_result",
      total_count: nil,
      url: "/v1/customers/search"
    }

    fixture = Helper.load_fixture("customer_search.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts a customer response with a list of sources properly" do
    expected_result = %Stripe.Customer{
      id: "cus_9ryX7lUQ4Dcpf7",
      object: "customer",
      created: 1_483_535_628,
      currency: "usd",
      default_source: nil,
      delinquent: false,
      description: nil,
      discount: nil,
      email: "test2@mail.com",
      livemode: false,
      metadata: %{},
      shipping: nil,
      sources: %Stripe.List{
        object: "list",
        data: [],
        has_more: false,
        total_count: 0,
        url: "/v1/customers/cus_9ryX7lUQ4Dcpf7/sources"
      },
      subscriptions: %Stripe.List{
        object: "list",
        data: [],
        has_more: false,
        total_count: 0,
        url: "/v1/customers/cus_9ryX7lUQ4Dcpf7/subscriptions"
      }
    }

    fixture = Helper.load_fixture("customer.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts a deleted response properly" do
    expected_result = %{
      deleted: true,
      id: "card_1A49JREym4h6pgdFkbcuN03L"
    }

    fixture = Helper.load_fixture("card_deleted.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "converts a checkout.session response properly" do
    expected_result = %Stripe.Checkout.Session{
      id: "CdWP8EBmSp1tJNIw4ZLF6w3XKd8MNKkEvlnSK7QmwFlDZ8rrjqBn9VI9vKiVdhfE",
      livemode: false,
      object: "checkout.session"
    }

    fixture = Helper.load_fixture("session.json")
    result = Converter.convert_result(fixture)

    assert result == expected_result
  end

  test "convering a tax settings object" do
    object = %{
      "id" => "evt_some_id",
      "object" => "event",
      "api_version" => "2020-08-27",
      "created" => 1_718_902_010,
      "data" => %{
        "object" => %{
          "object" => "tax.settings",
          "defaults" => %{
            "tax_behavior" => "inferred_by_currency",
            "tax_code" => "txcd_123456789"
          },
          "head_office" => %{
            "address" => %{
              "city" => "test",
              "country" => "PT",
              "line1" => "my test address",
              "line2" => nil,
              "postal_code" => "3000-100",
              "state" => nil
            }
          },
          "livemode" => true,
          "status" => "active",
          "status_details" => %{
            "active" => %{}
          }
        },
        "previous_attributes" => %{
          "defaults" => %{
            "tax_behavior" => nil,
            "tax_code" => nil
          },
          "head_office" => nil,
          "status" => "pending",
          "status_details" => %{
            "active" => nil,
            "pending" => %{
              "missing_fields" => [
                "head_office"
              ]
            }
          }
        }
      },
      "livemode" => true,
      "pending_webhooks" => 2,
      "request" => %{
        "id" => nil,
        "idempotency_key" => nil
      },
      "type" => "tax.settings.updated"
    }

    assert %Stripe.Event{
             account: nil,
             api_version: "2020-08-27",
             created: 1_718_902_010,
             data: %{
               object: %Stripe.Tax.Settings{
                 defaults: %{
                   tax_behavior: "inferred_by_currency",
                   tax_code: "txcd_123456789"
                 },
                 head_office: %{
                   address: %{
                     state: nil,
                     line1: "my test address",
                     city: "test",
                     country: "PT",
                     line2: nil,
                     postal_code: "3000-100"
                   }
                 },
                 livemode: true,
                 object: "tax.settings",
                 status: "active",
                 status_details: %{active: %{}}
               },
               previous_attributes: %{
                 status: "pending",
                 defaults: %{tax_behavior: nil, tax_code: nil},
                 head_office: nil,
                 status_details: %{
                   active: nil,
                   pending: %{missing_fields: ["head_office"]}
                 }
               }
             },
             id: "evt_some_id",
             livemode: true,
             object: "event",
             pending_webhooks: 2,
             request: %{id: nil, idempotency_key: nil},
             type: "tax.settings.updated"
           } = Converter.convert_result(object)
  end
end
